package spectra.ee.web.template;

import spectra.base.log.Logger;

/**
 * BoardNavigator에서 DB엑세스를 하지 않고 페이징를 나타나게 하기위한 클래스이다.
 * totalCount, rowsPerPage, currentPage만 가지고 페이징을 표시한다.
 * @author shchae
 */
public class BoardNavigatorBase
{

    /** Logger객체. */
    private static Logger logger = Logger.getLoggerInstance(BoardNavigatorBase.class.getName());

    /** 페이지 전체개수. */
    protected int totalCount = -1;

    /** 현재페이지. */
    protected int currentPage;

    /** 시작번호. */
    protected int startRecNo;

    /** 끝번호. */
    protected int endRecNo;

    /** 한페이지 나오는 글개수. */
    protected int rowsPerPage = 10;

    /** 페이지번호에 나오는 개수(1-2-3-4-5-6-7-8-9-10). */
    protected int unitCount =10;

    /** 개수 가져오는 query. */
    protected String countQuery="";

    /** 처음으로. */
    protected String toFirst = "◁◁";

    /** 끝으로. */
    protected String toEnd = "▷▷";

    /** 이전페이지. */
    protected String previous="◁";

    /** 다음페이지. */
    protected String forward ="▷";

    /** toFirst와 toEnd를 보여줄것인지. */
    protected boolean terminalDisplay = false;

    /** 이전,다음페이지를 보여줄것인지. */
    protected boolean nextAndPrevDisplay = true;

    /** 페이지번호 태그를 테이블로 감싸고 있을 때 시작 태그. */
    protected String strBoardTableStart = "";

    /** 페이지번호 태그를 테이블로 감싸고 있을 때 끝 태그. */
    protected String strBoardTableEnd = "";

    /** 이전 페이지 태그를 감싸고 있는 시작 태그. */
    protected String strPrevTagStart = "";

    /** 이전 페이지 태그를 감싸고 있는 끝 태그. */
    protected String strPrevTagEnd = "";

    /** 다음 페이지 태그를 감싸고 있는 시작 태그. */
    protected String strNextTagStart = "";

    /** 다음 페이지 태그를 감싸고 있는 끝 태그. */
    protected String strNextTagEnd = "";

    /** 첫 페이지 태그를 감싸고 있는 시작 태그. */
    protected String strFirstTagStart = "";

    /** 첫 페이지 태그를 감싸고 있는 끝 태그. */
    protected String strFirstTagEnd = "";

    /** 마지막 페이지 태그를 감싸고 있는 시작 태그. */
    protected String strEndTagStart = "";

    /** 마지막 페이지 태그를 감싸고 있는 끝 태그. */
    protected String strEndTagEnd = "";

    /** 페이지번호를 감싸고 있는 시작 태그. */
    protected String strPageTagStart = "";

    /** 페이지번호를 감싸고 있는 끝 태그. */
    protected String strPageTagEnd = "";

    /** 페이지번호를 감싸고 있는 마지막 시작 태그. */
    protected String strLastPageTagStart = "";

    /** 페이지번호를 감싸고 있는 마지막 끝 태그. */
    protected String strLastPageTagEnd = "";

    /** 태그 스타일 */
    protected String strTagStyle = "";

    /** 현재 번호를 강조하는 시작 태그. */
    protected String strCurrHighlightStart = "";

    /** 현재 번호를 강조하는 끝 태그. */
    protected String strCurrHighlightEnd = "";

    /** 전체갯수. */
    protected int totalUnits;

    /**
     * 생성자.
     *
     * @param totalCount 전체갯수.
     * @param rowsPerPage 한페이지 나오는 글 개수.
     * @param currentPage 현재페이지.
     */
    public BoardNavigatorBase(int totalCount, int rowsPerPage, int currentPage)
    {
        this.totalCount =  totalCount;
        this.rowsPerPage = rowsPerPage;
        this.currentPage = currentPage;
        setTotalCount(totalCount);
    }

    /**
     * 현재 번호를 강조하는 시작/끝 태그 설정.
     *
     * @param strStart 현재 번호를 강조하는 시작 태그.
     * @param strEnd 현재 번호를 강조하는 끝 태그.
     */
    public void setCurrHighlight(String strStart, String strEnd)
    {
        strCurrHighlightStart = strStart;
        strCurrHighlightEnd = strEnd;
    }

    /**
     * 태그 스타일을 설정한다.
     *
     * @param str 태그 스타일.
     */
    public void setStyle(String str)
    {
        strTagStyle = str;
    }

    /**
     * 페이지번호를 감싸고 있는 시작/끝 태그 설정.
     *
     * @param strStart 페이지번호를 감싸고 있는 시작 태그.
     * @param strEnd 페이지번호를 감싸고 있는 끝 태그.
     */
    public void setPageTags(String strStart, String strEnd)
    {
        strPageTagStart = strStart;
        strPageTagEnd = strEnd;
    }

    /**
     * 페이지번호를 감싸고 있는 마지막 시작/끝 태그 설정.
     *
     * @param strStart 페이지번호를 감싸고 있는 마지막 시작 태그.
     * @param strEnd 페이지번호를 감싸고 있는 마지막 끝 태그.
     */
    public void setLastPageTags(String strStart, String strEnd)
    {
        strLastPageTagStart = strStart;
        strLastPageTagEnd = strEnd;
    }

    /**
     * 페이지번호 태그를 테이블로 감싸고 있을 때 시작/끝 태그 설정.
     *
     * @param strStart 페이지번호 태그를 테이블로 감싸고 있을 때 시작 태그.
     * @param strEnd 페이지번호 태그를 테이블로 감싸고 있을 때 끝 태그.
     */
    public void setBoardTable(String strStart, String strEnd)
    {
        strBoardTableStart = strStart;
        strBoardTableEnd = strEnd;
    }

    /**
     * 첫 페이지 태그를 감싸고 있는 시작/끝 태그 설정.
     *
     * @param strStart 첫 페이지 태그를 감싸고 있는 시작 태그.
     * @param strEnd 첫 페이지 태그를 감싸고 있는 끝 태그.
     */
    public void setFirstTags(String strStart, String strEnd)
    {
        strFirstTagStart = strStart;
        strFirstTagEnd = strEnd;
    }

    /**
     * 마지막 페이지 태그를 감싸고 있는 시작/끝 태그 설정.
     *
     * @param strStart 마지막 페이지 태그를 감싸고 있는 시작 태그.
     * @param strEnd 마지막 페이지 태그를 감싸고 있는 끝 태그.
     */
    public void setEndTags(String strStart, String strEnd)
    {
        strEndTagStart = strStart;
        strEndTagEnd = strEnd;
    }

    /**
     * 이전 페이지 태그를 감싸고 있는 시작/끝 태그 설정.
     *
     * @param strStart 이전 페이지 태그를 감싸고 있는 시작 태그.
     * @param strEnd 이전 페이지 태그를 감싸고 있는 끝 태그.
     */
    public void setPrevTags(String strStart, String strEnd)
    {
        strPrevTagStart = strStart;
        strPrevTagEnd = strEnd;
    }

    /**
     * 다음 페이지 태그를 감싸고 있는 시작/끝 태그.
     *
     * @param strStart 다음 페이지 태그를 감싸고 있는 시작 태그.
     * @param strEnd 다음 페이지 태그를 감싸고 있는 끝 태그.
     */
    public void setNextTags(String strStart, String strEnd)
    {
        strNextTagStart = strStart;
        strNextTagEnd = strEnd;
    }

    /**
     * toFirstSymbol를 설정한다.
     *
     * @param str 첫페이지.
     */
    public void setToFirstSymbol(String str)
    {
        toFirst = str;
    }

    /**
     * toEndSymbol를 설정한다.
     *
     * @param str 마지막페이지.
     */
    public void setToEndSymbol(String str )
    {
        toEnd = str;
    }

    /**
     * forwardSymbol를 설정한다.
     *
     * @param str 다음페이지.
     */
    public void setForwardSymbol(String str)
    {
        forward = str;
    }

    /**
     * previousSymbol를 설정한다.
     *
     * @param str 이전페이지.
     */
    public void setPreviousSymbol(String str)
    {
        previous = str;
    }

    /**
     * imgToFirst를 설정한다.
     *
     * @param img 처음페이지(블럭)으로 이동.
     */
    public void setImgToFirst(String img)
    {
        setToFirstSymbol("<img src=" + img + " border=\"0\">");
    }

    /**
     * imgToEnd를 설정한다.
     *
     * @param img 마지막 페이지(블럭)로 이동.
     */
    public void setImgToEnd(String img)
    {
        setToEndSymbol("<img src=" + img + " border=\"0\">");
    }

    /**
     * imgForward를 설정한다.
     *
     * @param img 다음으로 이동.
     */
    public void setImgForward(String img)
    {
        setForwardSymbol("<img src=" + img + " border=\"0\">");
    }

    /**
     * imgPrevious를 설정한다.
     *
     * @param img 이전으로 이동.
     */
    public void setImgPrevious(String img)
    {
        setPreviousSymbol("<img src=" + img + " border=\"0\">");
    }

    /**
     * terminalDisplay를 설정한다.
     *
     * @param terminalDisplay toFirst와 toEnd를 보여줄것인지(true:보여줌, false:보여주지않음).
     */
    public void setTerminalDisplay(boolean terminalDisplay)
    {
        this.terminalDisplay = terminalDisplay;
    }

    /**
     * terminalDisplay를 얻는다.
     *
     * @return terminalDisplay toFirst와 toEnd를 보여줄것인지(true:보여줌, false:보여주지 않음)..
     */
    public boolean getTerminalDisplay()
    {
        return this.terminalDisplay;
    }

    /**
     * nextAndPrevDisplay를 설정한다.
     *
     * @param nextAndPrevDisplay 이전,다음페이지를 보여줄것인지(true:보여줌, false(보여주지 않음).
     */
    public void setNextAndPrevDisplay(boolean nextAndPrevDisplay)
    {
        this.nextAndPrevDisplay = nextAndPrevDisplay;
    }

    /**
     * nextAndPrevDisplay를 얻는다.
     *
     * @return nextAndPrevDisplay 이전,다음페이지를 보여줄것인지(true:보여줌, false(보여주지 않음).
     */
    public boolean getNextAndPrevDisplay()
    {
        return this.nextAndPrevDisplay;
    }

    /**
     * totalCount를 설정한다.
     *
     * @param cnt 전체갯수.
     */
    public void setTotalCount(int cnt)
    {
        totalCount = cnt;
        totalUnits = totalCount/rowsPerPage;
        totalUnits = (totalCount % rowsPerPage)== 0 ? totalUnits: totalUnits + 1;
    }

    /**
     * rowsPerPage를 설정한다.
     *
     * @param rp 한페이지 나오는 글개수.
     */
    public void setRowsPerPage(int rp)
    {
        rowsPerPage = rp;
    }

    /**
     * unitCount를 설정한다.
     *
     * @param unitCount 전체갯수.
     */
    public void setUnitCount(int unitCount)
    {
        this.unitCount = unitCount;
    }

    /**
     * unitCount를 얻는다.
     *
     * @return unitCount 전체갯수.
     */
    public int getUnitCount()
    {
        return this.unitCount;
    }

    /**
     * totalCount를 얻는다.
     *
     * @return totalCount 전체갯수.
     */
    public int getTotalCount()
    {
        return totalCount;
    }

    /**
     * countQuery를 얻는다.
     *
     * @return countQuery count쿼리.
     */
    public String getCountQuery()
    {
        return this.countQuery;
    }

    /**
     * countQuery를 설정한다.
     *
     * @param query count쿼리.
     */
    public void setCountQuery(String query)
    {
        this.countQuery = query;
    }

    /**
     * linkHtml를 얻는다.
     *
     * @return linkHtml 페이징Html.
     */
    public String getLinkHtml()
    {
        StringBuffer sb = new StringBuffer();
        if (currentPage < 0)
        {
            currentPage = 1;
        }
        else if (currentPage >= totalUnits)
        {
            currentPage = totalUnits;
        }
        //System.out.println("unitCount : "+unitCount);
        startRecNo = (currentPage - 1) * rowsPerPage + 1;
        endRecNo = startRecNo + rowsPerPage - 1;
        endRecNo = (endRecNo >= totalCount) ? totalCount: endRecNo;

        int backPageNo = (currentPage -1) / unitCount;// to determine back link to be displayed or not
        int startPageNo = backPageNo  * unitCount + 1;
        int pageNo = startPageNo;
        if (backPageNo >= 1)
        {
            if (terminalDisplay)
            {
                sb.append(strFirstTagStart + "<a href=\"JavaScript:goto(1);\" " + strTagStyle + ">" + toFirst+ "</a>" + strFirstTagEnd);
            }
            sb.append(strPrevTagStart + "<a href=\"JavaScript:goto(" +  ( startPageNo - unitCount) + ")\" " + strTagStyle + ">" + previous + "</a>" + strPrevTagEnd);
        }
        else if (nextAndPrevDisplay)
        {
            if (terminalDisplay)
            {
                sb.append(strFirstTagStart + "<a href='javascript:;' " + strTagStyle + ">" + toFirst+ "</a>" + strFirstTagEnd);
            }
            sb.append(strPrevTagStart + "<a href='javascript:;' " + strTagStyle + ">" + previous + "</a>" + strPrevTagEnd);
        }

        sb.append(strBoardTableStart);
        for (int i = 0; i < unitCount; i++)
        {
            pageNo = startPageNo + i;
            if(pageNo > totalUnits)
                break;

            if (pageNo == currentPage)
            {
                sb.append(strPageTagStart + "<a href='javascript:;'>" + strCurrHighlightStart + pageNo + strCurrHighlightEnd + "</a>" + strPageTagEnd);
            }
            else
            {
                sb.append(strPageTagStart + "<a href=\"JavaScript:goto(" + pageNo + ")\">" + pageNo+ "</a>" + strPageTagEnd);
            }
        }
        sb.append(strBoardTableEnd);

        int forwardPageCount = pageNo + 1;

        if (forwardPageCount <= totalUnits)
        {
            sb.append(strNextTagStart + "<a href=\"JavaScript:goto(" +  forwardPageCount + ")\" " + strTagStyle + ">" + forward + "</a>" + strNextTagEnd);
            if (terminalDisplay)
            {
                sb.append(strEndTagStart + "<a href=\"JavaScript:goto(" + totalUnits + ")\" " + strTagStyle + ">" + toEnd + "</a>" + strEndTagEnd);
            }
        }
        else if (nextAndPrevDisplay)
        {
            sb.append(strNextTagStart + "<a href='javascript:;' " + strTagStyle + ">" + forward + "</a>" + strNextTagEnd);
            if (terminalDisplay)
            {
                sb.append(strEndTagStart + "<a href='javascript:;' " + strTagStyle + ">" + toEnd + "</a>" + strEndTagEnd);
            }
        }
        return sb.toString();
    }

    /**
     * linkHtmlByTable를 얻는다.
     *
     * @return linkHtmlByTable 테이블 형태로 화면에 보여진는 html..
     */
    public String getLinkHtmlByTable()
    {
        return getLinkHtmlByTable(true, false, false, null);
    }

    /**
     * linkHtmlByTable를 얻는다.
     *
    * @param isDiplayFirstAndLast : 처음으로(◁◁), 마지막으로(▷▷) 링크를 화면에 보여지게 할 것인가? True이면 보여진다.
    * @param isDisplayNoLink : 처음으로(◁◁), 마지막으로(▷▷), 이전(◁), 다음(▷) 링크를 링크값이 없어도 화면에 보여지게 할 것인가? True이면 보여진다.
     *
     * @return linkHtmlByTable 테이블 형태로 화면에 보여진는 html..
     */
    public String getLinkHtmlByTable(boolean isDiplayFirstAndLast, boolean isDisplayNoLink)
    {
        return getLinkHtmlByTable(isDiplayFirstAndLast, isDisplayNoLink, false, null);
    }

    /**
    * <pre>
    * 테이블 형태로 화면에 디스플레이되며 주어진 값에 따라 화면 구성을 다르게한다.
    * </pre>
    *
    * @param isDiplayFirstAndLast : 처음으로(◁◁), 마지막으로(▷▷) 링크를 화면에 보여지게 할 것인가? True이면 보여진다.
    * @param isDisplayNoLink : 처음으로(◁◁), 마지막으로(▷▷), 이전(◁), 다음(▷) 링크를 링크값이 없어도 화면에 보여지게 할 것인가? True이면 보여진다.
    * @param isEnd : 처음으로(◁◁), 마지막으로(▷▷), 이전(◁), 다음(▷) 링크를 center가 아닌 right, left로 해서 양쪽 끝으로 화면에.... 디스플레이한다.
    * @param strWidth : 테이블 넓이
    *
    * @return LinkHtml 페이지 네비게이션 값
    */
    public String getLinkHtmlByTable(boolean isDiplayFirstAndLast, boolean isDisplayNoLink, boolean isEnd, String strWidth )
    {
        StringBuffer sb = new StringBuffer();
        if (currentPage < 0)
        {
            currentPage = 1;
        }
        else if (currentPage >= totalUnits)
        {
            currentPage = totalUnits;
        }

        startRecNo = (currentPage - 1) * rowsPerPage + 1;
        endRecNo = startRecNo + rowsPerPage - 1;
        endRecNo = (endRecNo >= totalCount) ? totalCount: endRecNo;

        int backPageNo = (currentPage -1) / unitCount;// to determine back link to be displayed or not
        int startPageNo = backPageNo  * unitCount + 1;
        int pageNo = startPageNo;

        if (strWidth != null )
        {
            strWidth = "width=\"" + strWidth + "\"";
        }
        else
        {
            strWidth = "";
        }


        if (backPageNo >= 1)
        {
            if (isDiplayFirstAndLast)
            {
                sb.append(strFirstTagStart + "<a href=\"JavaScript:goto(1);\" " + strTagStyle + ">" + toFirst+ "</a>" + strFirstTagEnd);
            }
            sb.append(strPrevTagStart + "<a href=\"JavaScript:goto(" +  ( startPageNo - unitCount) + ")\" " + strTagStyle + ">" + previous + "</a>" + strPrevTagEnd);
        }
        else
        {
            if (isDisplayNoLink)
            {
                if (isDiplayFirstAndLast)
                {
                    sb.append(strFirstTagStart + "<a " + strTagStyle + " >" + toFirst + "</a>" + strFirstTagEnd);
                }
                sb.append(strPrevTagStart + "<a " + strTagStyle + " >" + previous + "</a>" + strPrevTagEnd);
            }
        }

        sb.append(strBoardTableStart);
        for (int i = 0; i < unitCount; i++)
        {
            pageNo = startPageNo + i;
            if (pageNo > totalUnits)
                break;

            if (pageNo == currentPage)
            {
                if (pageNo == totalUnits || i == unitCount - 1)
                {
                    sb.append(strLastPageTagStart + "<a href=\"JavaScript:goto(" + pageNo + ")\">" + strCurrHighlightStart + pageNo + strCurrHighlightEnd + "</a>" + strLastPageTagEnd);
                }
                else
                {
                    sb.append(strPageTagStart + "<a href=\"JavaScript:goto(" + pageNo + ")\">" + strCurrHighlightStart + pageNo + strCurrHighlightEnd + "</a>" + strPageTagEnd);
                }
            }
            else
            {
                if (pageNo == totalUnits || i == unitCount - 1)
                {
                    sb.append(strLastPageTagStart + "<a href=\"JavaScript:goto(" + pageNo + ")\">" + pageNo+ "</a>" + strLastPageTagEnd);
                }
                else
                {
                    sb.append(strPageTagStart + "<a href=\"JavaScript:goto(" + pageNo + ")\">" + pageNo+ "</a>" + strPageTagEnd);
                }
            }
        }
        sb.append(strBoardTableEnd);

        int forwardPageCount = pageNo + 1;

        if (forwardPageCount <= totalUnits)
        {
            sb.append(strNextTagStart +"<a href=\"JavaScript:goto(" +  forwardPageCount + ")\"" + strTagStyle + ">" + forward + "</a>" + strNextTagEnd);
            if (isDiplayFirstAndLast)
            {
                sb.append(strEndTagStart + "<a href=\"JavaScript:goto(" + totalUnits + ")\" " + strTagStyle + ">" + toEnd + "</a>" + strEndTagEnd);
            }
        }
        else
        {
            if(isDisplayNoLink)
            {
                sb.append(strNextTagStart + "<a " + strTagStyle + " >" + forward + "</a>" + strNextTagEnd);
                if (isDiplayFirstAndLast)
                {
                    sb.append(strEndTagStart + "<a " + strTagStyle + " >" + toEnd + "</a>" + strEndTagEnd);
                }
            }
        }
        return sb.toString();
    }

    /**
     * start를 얻는다.
     *
     * @return start 시작번호.
     */
    public int getStart()
    {
        return startRecNo;
    }

    /**
     * rowsPerPage를 얻는다.
     *
     * @return rowsPerPage 한페이지 나오는 글개수.
     */
    public int getRowsPerPage()
    {
        return rowsPerPage;
    }

    /**
     * end를 얻는다.
     *
     * @return end 마지막번호.
     */
    public int getEnd()
    {
        return endRecNo;
    }
}